package cn.walls1717.mall.modules.pms.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.walls1717.mall.modules.pms.dto.ProductConditionDTO;
import cn.walls1717.mall.modules.pms.dto.ProductSaveParamDTO;
import cn.walls1717.mall.modules.pms.dto.ProductUpdateInitDTO;
import cn.walls1717.mall.modules.pms.model.PmsProduct;
import cn.walls1717.mall.modules.pms.mapper.PmsProductMapper;
import cn.walls1717.mall.modules.pms.service.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import net.sf.jsqlparser.expression.operators.relational.OldOracleJoinBinaryExpression;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Method;
import java.util.List;

/**
 * <p>
 * 商品信息 服务实现类
 * </p>
 *
 * @author walls1717
 * @since 2022-04-09
 */
@Service
public class PmsProductServiceImpl extends ServiceImpl<PmsProductMapper, PmsProduct> implements PmsProductService {

    private final PmsProductMapper mapper;
    private final PmsMemberPriceService memberPriceService;
    private final PmsProductLadderService ladderService;
    private final PmsProductFullReductionService fullReductionService;
    private final PmsSkuStockService skuStockService;
    private final PmsProductAttributeValueService attributeValueService;
    @Autowired
    public PmsProductServiceImpl(PmsProductMapper mapper, PmsMemberPriceService memberPriceService, PmsProductLadderService ladderService, PmsProductFullReductionService fullReductionService, PmsSkuStockService skuStockService, PmsProductAttributeValueService attributeValueService) {
        this.mapper = mapper;
        this.memberPriceService = memberPriceService;
        this.ladderService = ladderService;
        this.fullReductionService = fullReductionService;
        this.skuStockService = skuStockService;
        this.attributeValueService = attributeValueService;
    }

    @Override
    public Page<PmsProduct> pageList(ProductConditionDTO condition) {
        Page<PmsProduct> page = new Page<>(condition.getPageNum(), condition.getPageSize());
        LambdaQueryWrapper<PmsProduct> lqw = new LambdaQueryWrapper<>();
        if (!StrUtil.isBlank(condition.getKeyword())) {
            lqw.like(PmsProduct::getName, condition.getKeyword());
        }
        if (!StrUtil.isBlank(condition.getProductSn())) {
            lqw.eq(PmsProduct::getProductSn, condition.getProductSn());
        }
        if (condition.getBrandId() != null && condition.getBrandId() > 0) {
            lqw.eq(PmsProduct::getBrandId, condition.getBrandId());
        }
        if (condition.getProductCategoryId() != null && condition.getProductCategoryId() > 0) {
            lqw.eq(PmsProduct::getProductCategoryId, condition.getProductCategoryId());
        }
        if (condition.getPublishStatus() != null) {
            lqw.eq(PmsProduct::getPublishStatus, condition.getPublishStatus());
        }
        if (condition.getVerifyStatus() != null) {
            lqw.eq(PmsProduct::getVerifyStatus, condition.getVerifyStatus());
        }
        lqw.orderByDesc(PmsProduct::getSort);
        return this.page(page, lqw);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createProduct(ProductSaveParamDTO productSaveParamDTO) {
        PmsProduct product = productSaveParamDTO;
        product.setId(null);
        boolean result = this.save(product);
        if (result) {
            switch (product.getPromotionType()) {
                // 使用会员价
                case 2:
                    saveCreateRelaList(productSaveParamDTO.getMemberPriceList(), product.getId(), memberPriceService);
                    break;
                // 使用阶梯价格
                case 3:
                    saveCreateRelaList(productSaveParamDTO.getProductLadderList(), product.getId(), ladderService);
                    break;
                // 使用商品满减价格
                case 4:
                    saveCreateRelaList(productSaveParamDTO.getProductFullReductionList(), product.getId(), fullReductionService);
                    break;
                default:
            }
            // 保存 sku
            saveCreateRelaList(productSaveParamDTO.getSkuStockList(), product.getId(), skuStockService);
            // 保存 spu
            saveCreateRelaList(productSaveParamDTO.getProductAttributeValueList(), product.getId(), attributeValueService);
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateProduct(ProductSaveParamDTO productSaveParamDTO) {
        PmsProduct product = productSaveParamDTO;
        boolean result = this.updateById(product);
        if (result) {
            switch (product.getPromotionType()) {
                // 使用会员价
                case 2:
                    deleteCreateRelaList(product.getId(), memberPriceService);
                    saveCreateRelaList(productSaveParamDTO.getMemberPriceList(), product.getId(), memberPriceService);
                    break;
                // 使用阶梯价格
                case 3:
                    deleteCreateRelaList(product.getId(), ladderService);
                    saveCreateRelaList(productSaveParamDTO.getProductLadderList(), product.getId(), ladderService);
                    break;
                // 使用商品满减价格
                case 4:
                    deleteCreateRelaList(product.getId(), fullReductionService);
                    saveCreateRelaList(productSaveParamDTO.getProductFullReductionList(), product.getId(), fullReductionService);
                    break;
                default:
            }
            // 保存 sku
            deleteCreateRelaList(product.getId(), skuStockService);
            saveCreateRelaList(productSaveParamDTO.getSkuStockList(), product.getId(), skuStockService);
            // 保存 spu
            deleteCreateRelaList(product.getId(), attributeValueService);
            saveCreateRelaList(productSaveParamDTO.getProductAttributeValueList(), product.getId(), attributeValueService);
        }
        return result;
    }

    @Override
    public boolean updateStatus(List<Long> ids, PmsProduct product) {
        // 根据 ids 拿到所有需要修改的数据
        List<PmsProduct> products = this.listByIds(ids);
        for (PmsProduct pmsProduct : products) {
            // 给用来修改状态的临时实体对象id值，用来根据id修改
            product.setId(pmsProduct.getId());
            // 判断是否修改成功，失败直接返回false
            if (!this.updateById(product)) {
                return false;
            }
        }
        return true;
    }

    @Override
    public ProductUpdateInitDTO getOneProduct(Long id) {
        return mapper.getUpdateInfo(id);
    }

    public void deleteCreateRelaList(Long productId, IService service) {
        QueryWrapper qw = new QueryWrapper();
        qw.eq("product_id", productId);
        service.remove(qw);
    }

    /**
     * 保存创建商品时关联表数据
     * @param list 一张关联表可能保存多条数据
     * @param productId 商品id
     * @param service 相关表操作服务层
     */
    public void saveCreateRelaList(List list, Long productId, IService service) {
        if (CollectionUtil.isEmpty(list)) {
            return;
        }
        try {
            for (Object o : list) {
                Method setProductId = o.getClass().getMethod("setProductId", Long.class);
                // 在修改状态清除主键id
                Method setId = o.getClass().getMethod("setId", Long.class);
                setId.invoke(o,(Long)null);

                setProductId.invoke(o, productId);
            }
            service.saveBatch(list);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
